#pragma once

// Dependencies
namespace Core	{
	template<class T> class Point2_t;
	template<class T> class Vector2_t;
}

namespace Core {
	// Rect2_t
	// Represents a rectangle in 2D space
	template<class T>
	class Rect2_t {
	public: // Typedefs
		typedef T value_type;
		typedef Rect2_t<T> this_type;

	public: // Constructors
		Rect2_t();
		Rect2_t( T left, T bottom, T right, T top );

	public: // Named constructors
		// Construct a rectangle from x and y, and with and height
		static Rect2_t<T> fromSize( T x, T y, T w, T h );
		static Rect2_t<T> fromCenterSize( T x, T y, T w, T h );

	public: // Methods
		bool test( const Point2_t<T>& pt ) const;

		template<typename class F>
		void eachCorner( const F& f ) const {
			for ( int idx = 0; idx < 4; ++idx )
				f( corner(idx) );
		}

	public: // Accessors
		// Select a vertex from the Rect2_t, starting with 0=(left,bottom) and traversing counterclockwise to 3=(left, top)
		const Point2_t<T> corner( int idx ) const;
		const Point2_t<T> center() const;
		const Vector2_t<T> extents() const;
		T width() const;
		T height() const;

	private: // Static members
		static T this_type::* const corners[][2];	// List of pointer-to-member-variables that dictate which members of Rect2_t to use for which corner

	public: // Members
		T left, bottom, right, top;
	};

	// Typedefs available to the Core namespace
	typedef Rect2_t<int> Rect2i;
	typedef Rect2_t<float> Rect2f;
	typedef Rect2_t<double> Rect2;
}